package servlet;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import common.Ip;
import common.Servlet;
import common.Validate;
import dict.TransactionDict;
import dicts.RealmDict;
import net.sf.json.JSONObject;
import util.AgentUtil;
import util.HttpUtil;
import util.LogUtil;
import util.MmUtil;
import util.MobileUtil;
import utils.AesUtil;
import utils.DateUtil;
import utils.DigestUtil;
import utils.StringUtil;

public class Transport extends Servlet {

	private static final long serialVersionUID = 1L;

	public void process(HttpServletRequest request, HttpServletResponse response) throws Exception {

		String terminal = (MobileUtil.isMoblie(request)) ? "wap" : "web";

		// 校验参数 ( 名称,值,校验模式,边界 )
		List<Object[]> parameterList = Collections.synchronizedList(new ArrayList<Object[]>());
		parameterList.add(new Object[] { "version", request.getParameter("version"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "no", request.getParameter("no"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "order", request.getParameter("order"), Validate.NOTEMPTY | Validate.CHARNUMBER | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "cvc", request.getParameter("cvc"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 100 });
		parameterList.add(new Object[] { "order", request.getParameter("order"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "site", request.getParameter("site"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH | Validate.NOHTTPHEADER, 0, 100 });
		parameterList.add(new Object[] { "cur", request.getParameter("cur"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "loc", request.getParameter("loc"), Validate.NOTEMPTY | Validate.ISNUMBER | Validate.EXCEEDNUMBER, 0, Integer.MAX_VALUE });
		parameterList.add(new Object[] { "notify", request.getParameter("notify"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH | Validate.HTTPHEADER, 0, 500 });
		parameterList.add(new Object[] { "finger", request.getParameter("finger"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "timing", request.getParameter("timing"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "product", request.getParameter("product"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 500 });
		parameterList.add(new Object[] { "cfname", request.getParameter("cfname"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "clname", request.getParameter("clname"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "cphone", request.getParameter("cphone"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "cemail", request.getParameter("cemail"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH | Validate.EMAILFORMAT, 0, 100 });
		parameterList.add(new Object[] { "ccountry", request.getParameter("ccountry"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "cstate", request.getParameter("cstate"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "ccity", request.getParameter("ccity"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "caddr", request.getParameter("caddr"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 200 });
		parameterList.add(new Object[] { "czip", request.getParameter("czip"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "hfname", request.getParameter("hfname"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "hlname", request.getParameter("hlname"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "hphone", request.getParameter("hphone"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "hemail", request.getParameter("hemail"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH | Validate.EMAILFORMAT, 0, 100 });
		parameterList.add(new Object[] { "hcountry", request.getParameter("hcountry"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "hstate", request.getParameter("hstate"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "hcity", request.getParameter("hcity"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "haddr", request.getParameter("haddr"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 200 });
		parameterList.add(new Object[] { "hzip", request.getParameter("hzip"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });

		JSONObject validateResult = Validate.validate(parameterList);

		if (!StringUtil.isEmpty(validateResult)) {
			request.setAttribute("code", validateResult.get("code"));
			request.setAttribute("message", validateResult.get("message"));
			request.getRequestDispatcher("/core/" + terminal + "/result.jsp").forward(request, response);
			return;
		}

		Map<String, String> requestMap = new HashMap<String, String>();
		JSONObject responseMap = new JSONObject();

		requestMap.put("version", request.getParameter("version"));
		requestMap.put("order", request.getParameter("order"));
		requestMap.put("site", request.getParameter("site"));
		requestMap.put("cur", request.getParameter("cur"));
		requestMap.put("loc", request.getParameter("loc"));
		requestMap.put("notify", request.getParameter("notify"));
		requestMap.put("product", request.getParameter("product"));
		requestMap.put("finger", request.getParameter("finger"));
		requestMap.put("timing", request.getParameter("timing"));
		requestMap.put("cfname", request.getParameter("cfname"));
		requestMap.put("clname", request.getParameter("clname"));
		requestMap.put("cphone", request.getParameter("cphone"));
		requestMap.put("cemail", request.getParameter("cemail"));
		requestMap.put("ccountry", request.getParameter("ccountry"));
		requestMap.put("cstate", request.getParameter("cstate"));
		requestMap.put("ccity", request.getParameter("ccity"));
		requestMap.put("caddr", request.getParameter("caddr"));
		requestMap.put("czip", request.getParameter("czip"));
		requestMap.put("hfname", request.getParameter("hfname"));
		requestMap.put("hlname", request.getParameter("hlname"));
		requestMap.put("hphone", request.getParameter("hphone"));
		requestMap.put("hemail", request.getParameter("hemail"));
		requestMap.put("hcountry", request.getParameter("hcountry"));
		requestMap.put("hstate", request.getParameter("hstate"));
		requestMap.put("hcity", request.getParameter("hcity"));
		requestMap.put("haddr", request.getParameter("haddr"));
		requestMap.put("hzip", request.getParameter("hzip"));

		try {
			requestMap.put("no", AesUtil.AES_Decrypt(AesUtil.KEY, request.getParameter("no")));
			requestMap.put("ip", Ip.getIp(request));
			requestMap.put("os", AgentUtil.getOs(request.getHeader("User-Agent")));
			requestMap.put("browser", AgentUtil.getBrowser(request.getHeader("User-Agent")));
			requestMap.put("locale", request.getLocale().getCountry() + "|" + request.getLocale().getLanguage());
			requestMap.put("number", AesUtil.AES_Encrypt(DigestUtil.md5(AesUtil.AES_Decrypt(AesUtil.KEY, request.getParameter("key"))), MmUtil.desnet(request.getParameter("cvc")).substring(0, 16)));
			requestMap.put("expire", AesUtil.AES_Encrypt(DigestUtil.md5(AesUtil.AES_Decrypt(AesUtil.KEY, request.getParameter("key"))), MmUtil.desnet(request.getParameter("cvc")).substring(16, 20)));
			requestMap.put("cvv", AesUtil.AES_Encrypt(DigestUtil.md5(AesUtil.AES_Decrypt(AesUtil.KEY, request.getParameter("key"))), MmUtil.desnet(request.getParameter("cvc")).substring(20, 23)));
			requestMap.put("signature", DigestUtil.sha256(requestMap.get("no") + requestMap.get("order") + requestMap.get("cur") + requestMap.get("loc") + AesUtil.AES_Decrypt(AesUtil.KEY, request.getParameter("key"))));
		} catch (Exception e) {
			LogUtil.transport(DateUtil.format(new Date(), DateUtil.DATETIMENOSPACE) + " " + e.getMessage());
			request.setAttribute("code", TransactionDict.CONVERSION_EXCEPTION);
			request.setAttribute("message", TransactionDict.MESSAGES.get(TransactionDict.CONVERSION_EXCEPTION));
			request.getRequestDispatcher("/core/" + terminal + "/result.jsp").forward(request, response);
			return;
		}

		try {
			String result = new HttpUtil().post(RealmDict.GATEWAY + "Entrance", requestMap);
			LogUtil.transport(DateUtil.format(new Date(), DateUtil.DATETIMENOSPACE) + " " + RealmDict.GATEWAY + "Entrance?" + requestMap);
			LogUtil.transport(DateUtil.format(new Date(), DateUtil.DATETIMENOSPACE) + " " + result);
			responseMap = JSONObject.fromObject(result);
			request.setAttribute("code", responseMap.get("code"));
			request.setAttribute("message", responseMap.get("message"));
			request.getRequestDispatcher("/core/" + terminal + "/finish.jsp").forward(request, response);
			return;
		} catch (Exception e) {
			LogUtil.transport(DateUtil.format(new Date(), DateUtil.DATETIMENOSPACE) + " " + e.getMessage());
			request.setAttribute("code", TransactionDict.CONNECTION_EXCEPTION);
			request.setAttribute("message", TransactionDict.MESSAGES.get(TransactionDict.CONNECTION_EXCEPTION));
			request.getRequestDispatcher("/core/" + terminal + "/result.jsp").forward(request, response);
			return;
		}

	}

}
